package com.cloudkinto.common.common;

import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.exception.BizException;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;

import java.io.*;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.text.DecimalFormat;

import static java.lang.String.format;

/**
 * @author fanting
 * @date 2018-08-09
 */
public class FileUtils {

    static final int KIB = 1024;
    public static final long NORMAL_FILE_SIZE = 2 * KIB * KIB;
    static final String ZERO = "0";
    static final String[] UNITS = new String[]{"b", "kb", "Mb", "Gb", "Tb"};
    static final String DECIMAL_FORMAT_PATTERN = "#,##0.#";
    static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat(DECIMAL_FORMAT_PATTERN);

    public static final int BUFFER_SIZE = 4096;

    /**
     * 判断是否是大文件 主要用于复制文件时的策略
     *
     * @param size
     * @return
     */
    public static boolean isLarge(long size) {
        return size > NORMAL_FILE_SIZE;
    }

    /**
     * 显示大小
     *
     * @param size
     * @return
     */
    public static String toString(final long size) {
        if (size < 1) {
            return ZERO;
        }
        val digitGroups = (int) (Math.log10(size) / Math.log10(KIB));
        val amount = DECIMAL_FORMAT.format(size / Math.pow(KIB, digitGroups));
        val unit = UNITS[digitGroups];
        return format("%s %s", amount, unit);
    }

    /**
     * 通过文件uuid，算出文件最终实际存储地址 此处主要通过uuid的前8位来进行文件散列 保证基本大型散列目录内，不会超过 36 * 36 个文件目录
     *
     * @param uuid
     * @return
     */
    public static String hashPath(String uuid) {
        if (StringUtils.isBlank(uuid)) {
            return null;
        }
        String regex = "(.{2})";
        String uuids = uuid.replaceAll(regex, "$1,");
        String[] uuidList = uuids.split(",");
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            sb.append(uuidList[i]).append(File.separator);
        }
        return sb.toString();
    }

    /**
     * 获取本地文件的 mime type
     *
     * @param filePath
     * @return
     * @throws IOException
     */
    public static String getMimeType(String filePath) throws IOException {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String type = fileNameMap.getContentTypeFor(filePath);
        return type;
    }

    /**
     * 创建目录
     *
     * @param dir
     */
    public static void make(String dir) {
        File file = new File(dir);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    /**
     * 文件上传
     *
     * @param in
     * @param filePath
     */
    public static void uploadFile(InputStream in, String filePath) {
        OutputStream out = null;
        try {
            out = new FileOutputStream(filePath);
            copy(in, out);
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                in.close();
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 从输入流拷贝文件到输出流
     *
     * @param in
     * @param out
     * @return
     * @throws IOException
     */
    public static int copy(InputStream in, OutputStream out) throws IOException {
        try {
            int byteCount = 0;
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead = -1;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
                byteCount += bytesRead;
            }
            out.flush();
            return byteCount;
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
            }
            try {
                out.close();
            } catch (IOException ex) {
            }
        }
    }

    public static byte[] readByte(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new BizException(SysConstant.File_NotExist);
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(file));
            int buf_size = 1024;
            byte[] buffer = new byte[buf_size];
            int len = 0;
            while (-1 != (len = in.read(buffer, 0, buf_size))) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bos.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
        return null;
    }

    public static void writeByteArrayToFile(File newFile, byte[] certData) {

    }
}
